from fastapi import APIRouter, Depends
from schema.resp import RestfulModel
from dependencies import get_mongo_db_of_condition_safety
from typing import List
from pymongo.database import Database
import utils
from random import randint
import hashlib
from datetime import datetime, timedelta, date
import pandas as pd
import re

condition_safety_attack_detail_router = APIRouter(prefix='/condition_safety/attack_detail', tags=['车辆状态安全-攻击详情'])


class MongoCollectionName:
    """
    mongo 中 collection 的 name 常量
    """
    ATTACK_DISPLAY='Attack_situation_display'
    ATTACK_STATISTICS='Attack_Statistics'
    KAFKA_DATA='kafka_raw_data'


#获取不同攻击类型次数统计数据 vehicle_status/attack_detail/statistics
#total_attack_num  int 总攻击次数
#DDOS_attack_num
#APT_attack_num
#virus_attack_num
@condition_safety_attack_detail_router.get('/statistics',summary='不同攻击类型次数统计')
async def get_attack_statistics(mongo_db: Database = Depends(get_mongo_db_of_condition_safety)):
    kafka_col = mongo_db[MongoCollectionName.KAFKA_DATA]

    # "HTTP","Dos","port scan","blocked ip"

    http_cursor = kafka_col.find({'type':re.compile('HTTP')})
    http_result = []
    for u in http_cursor:
        http_result.append(u)
    http_attack_num=len(http_result)

    Dos_cursor = kafka_col.find({"type": re.compile("Dos")})
    Dos_result = []
    for u in Dos_cursor:
        Dos_result.append(u)
    Dos_attack_num = len(Dos_result)

    port_scan_cursor = kafka_col.find({"type": re.compile("port scan")})
    port_scan_result = []
    for u in port_scan_cursor:
        port_scan_result.append(u)
    port_scan_attack_num = len(port_scan_result)

    blocked_ip_cursor = kafka_col.find({"type": re.compile("blocked ip")})
    blocked_ip_result = []
    for u in blocked_ip_cursor:
        blocked_ip_result.append(u)
    blocked_ip_attack_num = len(blocked_ip_result)

    total_attack_num=http_attack_num+Dos_attack_num+port_scan_attack_num+blocked_ip_attack_num

    result={
        'total_attack_num':total_attack_num,
        'http_attack_num':http_attack_num,
        'Dos_attack_num':Dos_attack_num,
        'port_scan_attack_num':port_scan_attack_num,
        'blocked_ip_attack_num':blocked_ip_attack_num
    }
    return RestfulModel.success(result)


def week_day_get(d):
    for i in range(0,8):
        oneday = timedelta(days=i)
        day = d - oneday
        date_to = datetime(day.year, day.month, day.day)
        yield str(date_to)[:]


def display(day_list, res):
    flag = 0
    count_result = []
    for type in ["HTTP","Dos","port scan","blocked ip"]:
        for time in day_list:
            for i in res:
                if i['type'] == type and i['time'].date() == datetime.strptime(time, '%Y-%m-%d %H:%M:%S').date():
                    count_result.append(i)
                    flag = 1
                    break
            if flag == 1:
                flag = 0
                continue
            else:
                data = {
                    'type': type,
                    'time': datetime.strptime(time, '%Y-%m-%d %H:%M:%S'),
                    'count': 0
                }
                count_result.append(data)

    n=len(day_list)
    HTTP=[0]*n
    Dos=[0]*n
    port_scan=[0]*n
    blocked_ip=[0]*n
    for data in count_result:
        time=str(data['time']).split(' ')[0]+' '+'00:00:00'
        if data['type']=='HTTP':
            HTTP[day_list.index(time)]=data['count']
        elif data['type']=='Dos':
            Dos[day_list.index(time)]=data['count']
        elif data['type']=='port scan':
            port_scan[day_list.index(time)]=data['count']
        elif data['type']=='blocked ip':
            blocked_ip[day_list.index(time)]=data['count']

    result={
        'x':day_list,
        'y':{
            'HTTP':HTTP,
            'Dos':Dos,
            'port_scan':port_scan,
            'blocked_ip':blocked_ip
        }
    }
    return result


#获取本周攻击次数的趋势数据 /vehicle_status/attack_detail/trend/{attack_type}
#请求参数：attack_type
#x  本周日期列表
#y attack_num 本周攻击次数列表
@condition_safety_attack_detail_router.get('/trend/{attack_type}',summary='本周攻击次数的趋势,{attack_type}可选HTTP/Dos/port_scan/blocked_ip')
async def get_attack_trend(attack_type,mongo_db: Database = Depends(get_mongo_db_of_condition_safety)):
    attack_data=[]
    kafka_col = mongo_db[MongoCollectionName.KAFKA_DATA]
    for x in kafka_col.find():
        attack_data.append(x)

    res = []
    flag = 0
    for res_data in attack_data:
        for i in res:
            if res_data['time'].date() == i['time'].date() and res_data['type'].split('_')[0] == i['type']:
                i['count'] += 1
                flag = 1
                break
        if flag == 1:
            flag = 0
            continue
        else:
            data_new = {
                'type': res_data['type'].split('_')[0],
                'time': res_data['time'],
                'count': 1
            }
            res.append(data_new)

    d = datetime.now()

    week_days = week_day_get(d)
    week_list = []
    for obj in week_days:
        week_list.append(obj)
    list_week_day = week_list[::-1]

    display_all = display(list_week_day, res)
    result={
        'x':list_week_day,
        'y':display_all['y'][attack_type]
    }

    return RestfulModel.success(result)


#获取攻击详情展示列表 vehicle_status/attack_detail/list
#请求参数：keywords page size
#total_page 总页数
#total_count 总记录数
#docs
@condition_safety_attack_detail_router.get('/list',summary='攻击详情展示列表')
async def get_attack_list(page=1,size=8,mongo_db: Database = Depends(get_mongo_db_of_condition_safety)):
    kafka_col = mongo_db[MongoCollectionName.KAFKA_DATA]
    cursor = kafka_col.find({},{ '_id':0})
    data=[]
    for u in cursor:
        data.append(u)

    total_count=len(data)
    total_page=int((total_count + int(size) - 1) / int(size))
    docs=data[(int(page)-1)*int(size):int(page)*int(size)]
    result={
        'total_page':total_page,
        'total_count':total_count,
        'docs':docs
    }
    return RestfulModel.success(result)


#获取攻击排名 vehicle_status/attack_detail/sort
#virus_attack_num
#DDos_attack_num
#APT_attack_num
@condition_safety_attack_detail_router.get('/sort',summary='攻击排名')
async def get_attack_sort(mongo_db: Database = Depends(get_mongo_db_of_condition_safety)):
    kafka_col = mongo_db[MongoCollectionName.KAFKA_DATA]

    # "HTTP","Dos","port scan","blocked ip"

    http_cursor = kafka_col.find({'type': re.compile('HTTP')})
    http_result = []
    for u in http_cursor:
        http_result.append(u)
    http_attack_num = len(http_result)

    Dos_cursor = kafka_col.find({"type": re.compile("Dos")})
    Dos_result = []
    for u in Dos_cursor:
        Dos_result.append(u)
    Dos_attack_num = len(Dos_result)

    port_scan_cursor = kafka_col.find({"type": re.compile("port scan")})
    port_scan_result = []
    for u in port_scan_cursor:
        port_scan_result.append(u)
    port_scan_attack_num = len(port_scan_result)

    blocked_ip_cursor = kafka_col.find({"type": re.compile("blocked ip")})
    blocked_ip_result = []
    for u in blocked_ip_cursor:
        blocked_ip_result.append(u)
    blocked_ip_attack_num = len(blocked_ip_result)


    result = {
        'http_attack_num': http_attack_num,
        'Dos_attack_num': Dos_attack_num,
        'port_scan_attack_num': port_scan_attack_num,
        'blocked_ip_attack_num': blocked_ip_attack_num
    }

    result_order = sorted(result.items(), key=lambda x: x[1], reverse=True)
    result_order_dict=dict(result_order)

    return RestfulModel.success(result_order_dict)

